(function () {
  class Navigator {
    constructor(jsPlumbInstance, options) {
      this.jsPlumbInstance = jsPlumbInstance;
      this.options = options;
      this.canvasEle = this.jsPlumbInstance.defaults.container;
      this.canvasTransform = this.canvasEle.style.transform;
      this.viewportEle = this.canvasEle.offsetParent;
      this.viewportEle.addEventListener('mousewheel', this.handleMiddleMouseScrollAndZoom.bind(this));
      this.viewportEle.onpointerdown = this.handleViewportPointerDown.bind(this);
      this.viewportEle.onpointerup = this.handleViewportPointerUp.bind(this);
      if (!options.disableMiniMap) {
        this.miniMapEle = this.createMiniMapEle();
        this.viewportEle.appendChild(this.miniMapEle);
        this.miniMap = new MiniMap(this, this.canvasEle, this.miniMapEle);
      }
      if (!options.disableToolbar) {
        this.toolbarEle = this.createToolbarEle();
        this.viewportEle.appendChild(this.toolbarEle);
        this.toolbar = new Toolbar(this, this.toolbarEle);
      }
      this.startAnimationFrame();
      this.bestFit();
    }

    handleMiddleMouseScrollAndZoom(e) {
      let scale = this.getCanvasScale();
      if (e.ctrlKey) {
        if (e.wheelDeltaY > 0) {
          scale += 0.1;
        } else {
          scale -= 0.1;
        }
        scale = Math.max(0.1, scale);
        scale = Math.min(3, scale);
        this.zoomTo(scale);
      } else {
        let { left, top } = this.getCanvasBounds();
        if (e.wheelDeltaY > 0) {
          top += 50 / scale;
        } else {
          top -= 50 / scale;
        }
        this.setCanvasLocationAndScale(left, top, scale);
      }
      e.preventDefault();
      e.stopPropagation();
    }

    handleViewportPointerDown(e) {
      if (e.target === this.viewportEle) {
        let x = 0;
        let y = 0;
        let firstMove = true;
        this.viewportEle.onpointermove = e => {
          if (e.buttons !== 1) {
            this.viewportEle.onpointermove = null;
            this.viewportEle.releasePointerCapture(e.pointerId);
            return;
          }
          if (Math.abs(x) > 5 || Math.abs(y) > 5) {
            this.pan(e.movementX, e.movementY);
            if (firstMove) {
              this.viewportEle.style.cursor = 'grabbing';
              this.viewportEle.setPointerCapture(e.pointerId);
              firstMove = false;
            }
          } else {
            x += e.movementX;
            y += e.movementY;
          }
        };
      }
    }

    handleViewportPointerUp(e) {
      this.viewportEle.onpointermove = null;
      this.viewportEle.releasePointerCapture(e.pointerId);
      this.viewportEle.style.cursor = null;
    }

    createMiniMapEle() {
      const { miniMapWidth, miniMapHeight, miniMapPosition } = this.options;
      const ele = document.createElement('div');
      ele.className = 'minimap';
      ele.style.position = 'absolute';
      ele.style.width = `${miniMapWidth}px`;
      ele.style.height = `${miniMapHeight}px`;
      ele.style.overflow = 'hidden';
      ele.style.backgroundColor = '#eee';
      const margin = '4px';
      switch (miniMapPosition) {
        case 'top-left':
          ele.style.left = margin;
          ele.style.top = margin;
          break;
        case 'top-right':
          ele.style.right = margin;
          ele.style.top = margin;
          break;
        case 'bottom-left':
          ele.style.left = margin;
          ele.style.bottom = margin;
          break;
        default:
          ele.style.right = margin;
          ele.style.bottom = margin;
          break;
      }
      return ele;
    }

    createToolbarEle() {
      const ele = document.createElement('div');
      ele.className = 'toolbar';
      ele.style.position = 'absolute';
      ele.style.overflow = 'hidden';
      ele.style.boxShadow = '0 0 2px 1px rgba(0, 0, 0, 0.08)';
      const margin = '4px';
      switch (this.options.toolbarPosition) {
        case 'top-left':
          ele.style.left = margin;
          ele.style.top = margin;
          break;
        case 'top-right':
          ele.style.right = margin;
          ele.style.top = margin;
          break;
        case 'bottom-right':
          ele.style.right = margin;
          ele.style.bottom = margin;
          break;
        default:
          ele.style.left = margin;
          ele.style.bottom = margin;
          break;
      }
      return ele;
    }

    setCanvasTransform() {
      if (this.canvasTransform && this.canvasTransform !== this.canvasEle.style.transform) {
        this.canvasEle.style.transform = this.canvasTransform;
      }
      if (!this.isDisposed) {
        this.setCanvasTransformFrameHandle = window.requestAnimationFrame(() => this.setCanvasTransform());
      }
    }

    startAnimationFrame() {
      this.setCanvasTransform();
    }

    stopAnimationFrame() {
      this.canvasTransform = undefined;
      if (this.setCanvasTransformFrameHandle) {
        window.cancelAnimationFrame(this.setCanvasTransformFrameHandle);
      }
    }

    getCanvasScale() {
      let scale = 1;
      const transform = this.canvasTransform;
      if (transform) {
        const index = transform.indexOf('scale(');
        if (index > -1) {
          scale = parseFloat(transform.substring(index + 6, transform.indexOf(')', index)));
        }
      }
      return scale;
    }

    getCanvasBounds() {
      let left = 0;
      let top = 0;
      const transform = this.canvasTransform;
      if (transform) {
        const index = transform.indexOf('translate(');
        if (index > -1) {
          const offset = transform.substring(index + 10, transform.indexOf(')', index));
          left = parseFloat(offset.split(',')[0]);
          top = parseFloat(offset.split(',')[1]);
        }
      }
      return {
        left,
        top,
        width: this.canvasEle.offsetWidth,
        height: this.canvasEle.offsetHeight,
      };
    }

    getCanvasActualBounds() {
      let left, right, top, bottom;
      const canvasBounds = this.getCanvasBounds();
      const elements = this.jsPlumbInstance.getManagedElements();
      for (const key in elements) {
        const ele = elements[key].el;
        const offset = { left: ele.offsetLeft, top: ele.offsetTop };
        const size = { width: ele.offsetWidth, height: ele.offsetHeight };
        left = left === undefined ? offset.left : Math.min(left, offset.left);
        top = top === undefined ? offset.top : Math.min(top, offset.top);
        right = right === undefined ? offset.left + size.width : Math.max(right, offset.left + size.width);
        bottom = bottom === undefined ? offset.top + size.height : Math.max(bottom, offset.top + size.height);
      }
      return {
        left: canvasBounds.left + left,
        top: canvasBounds.top + top,
        width: right - left,
        height: bottom - top,
      };
    }

    setCanvasLocation(left, top, force) {
      this.setCanvasLocationAndScale(left, top, this.getCanvasScale(), force);
    }

    setCanvasLocationAndScale(left, top, scale, force) {
      this.canvasTransform = `scale(${scale}) translate(${left}px, ${top}px)`;
      if (force) {
        this.canvasEle.style.transform = this.canvasTransform;
      }
    }

    getCanvasScaleBounds() {
      const scale = this.getCanvasScale();
      const bounds = this.getCanvasBounds();
      return {
        left: bounds.left,
        top: bounds.top,
        width: bounds.width * scale,
        height: bounds.height * scale,
      };
    }

    getViewportBounds() {
      return {
        left: 0,
        top: 0,
        width: this.viewportEle.offsetWidth,
        height: this.viewportEle.offsetHeight,
      };
    }

    viewportPointToCanvans(point) {
      const canvasBounds = this.getCanvasBounds();
      const canvasScale = this.getCanvasScale();
      return {
        x: point.x / canvasScale - canvasBounds.left,
        y: point.y / canvasScale - canvasBounds.top,
      };
    }

    pan(offsetX, offsetY) {
      const scale = this.getCanvasScale();
      const bounds = this.getCanvasBounds();
      const left = bounds.left + offsetX / scale;
      const top = bounds.top + offsetY / scale;
      this.setCanvasLocation(left, top);
    }

    zoomTo(scale, viewportPoint) {
      const viewportBounds = this.getViewportBounds();
      viewportPoint = viewportPoint ?? {
        x: viewportBounds.left + viewportBounds.width / 2,
        y: viewportBounds.top + viewportBounds.height / 2,
      };
      const canvasPoint = this.viewportPointToCanvans(viewportPoint);
      const left = viewportPoint.x - canvasPoint.x * scale;
      const top = viewportPoint.y - canvasPoint.y * scale;
      this.setCanvasLocationAndScale(left / scale, top / scale, scale);
      this.jsPlumbInstance.setZoom(scale);
    }

    zoomIn() {
      this.zoomTo(Math.min(3, this.getCanvasScale() + 0.1));
    }

    zoomOut() {
      this.zoomTo(Math.max(0.1, this.getCanvasScale() - 0.1));
    }

    zoomTo100() {
      this.zoomTo(1);
    }

    bestFit() {
      const viewportBounds = this.getViewportBounds();
      const canvasBounds = this.getCanvasBounds();
      const canvasActualBounds = this.getCanvasActualBounds();
      let scale = viewportBounds.width / canvasActualBounds.width;
      scale = Math.min(1, scale);
      scale = Math.max(0.5, scale);
      const width = canvasActualBounds.width * scale;
      const height = canvasActualBounds.height * scale;
      const left = viewportBounds.left + (viewportBounds.width - width) / 2 - (canvasActualBounds.left - canvasBounds.left) * scale;
      let top = 0;
      if (viewportBounds.height > height) {
        top = viewportBounds.top + (viewportBounds.height - height) / 2 - (canvasActualBounds.top - canvasBounds.top) * scale;
      } else {
        top = viewportBounds.top - (canvasActualBounds.top - canvasBounds.top) * scale;
      }
      this.setCanvasLocationAndScale(left / scale, top / scale, scale, true);
      this.jsPlumbInstance.setZoom(scale);
      return scale;
    }

    fitToViewport() {
      const viewportBounds = this.getViewportBounds();
      const canvasBounds = this.getCanvasBounds();
      const canvasActualBounds = this.getCanvasActualBounds();
      let scale = 1;
      if (viewportBounds.width / viewportBounds.height > canvasActualBounds.width / canvasActualBounds.height) {
        scale = viewportBounds.height / canvasActualBounds.height;
      } else {
        scale = viewportBounds.width / canvasActualBounds.width;
      }
      const width = canvasActualBounds.width * scale;
      const height = canvasActualBounds.height * scale;
      const left = viewportBounds.left + (viewportBounds.width - width) / 2 - (canvasActualBounds.left - canvasBounds.left) * scale;
      const top = viewportBounds.top + (viewportBounds.height - height) / 2 - (canvasActualBounds.top - canvasBounds.top) * scale;
      this.setCanvasLocationAndScale(left / scale, top / scale, scale, true);
      this.jsPlumbInstance.setZoom(scale);
      return scale;
    }

    getMiniMapVisible() {
      return this.miniMapEle && this.miniMapEle.style.display !== 'none';
    }

    showMiniMap() {
      if (this.miniMapEle && this.miniMap) {
        this.miniMapEle.style.display = 'block';
        this.miniMap.refresh(true);
      }
    }

    hideMiniMap() {
      if (this.miniMapEle) {
        this.miniMapEle.style.display = 'none';
      }
    }

    getToolbarVisible() {
      return this.toolbarEle && this.toolbarEle.style.display !== 'none';
    }

    showToolbar() {
      if (this.toolbarEle) {
        this.toolbarEle.style.display = 'block';
      }
    }

    hideToolbar() {
      if (this.toolbarEle) {
        this.toolbarEle.style.display = 'none';
      }
    }

    dispose() {
      this.stopAnimationFrame();
      this.miniMap?.dispose();
      this.viewportEle.onpointerdown = null;
      this.viewportEle.onpointermove = null;
      this.viewportEle.onpointerup = null;
      this.viewportEle.removeEventListener('mousewheel', this.middleMouseZoomHandle);
      this.isDisposed = true;
    }
  }

  class MiniMap {
    constructor(navigator, canvasEle, miniMapEle) {
      this.navigator = navigator;
      this.canvasEle = canvasEle;
      this.miniMapEle = miniMapEle;
      this.miniMapViewportEle = this.createMiniMapViewportEle();
      this.miniMapCanvasEle = this.createMiniMapCanvasEle();
      this.miniMapViewportEle.appendChild(this.miniMapCanvasEle);
      this.miniMapEle.appendChild(this.miniMapViewportEle);
      this.miniMapEle.addEventListener('mousewheel', this.handleMiddleMouseZoom.bind(this));
      this.miniMapEle.onpointerdown = this.handlePointerDown.bind(this);
      this.miniMapEle.onpointerup = this.handlePointerUp.bind(this);
      this.refresh(true);
    }

    handleMiddleMouseZoom(e) {
      let scale = this.navigator.getCanvasScale();
      if (e.wheelDeltaY > 0) {
        scale += 0.1;
      } else {
        scale -= 0.1;
      }
      scale = Math.max(0.1, scale);
      scale = Math.min(3, scale);
      this.navigator.zoomTo(scale);
      this.layout();
      e.preventDefault();
      e.stopPropagation();
    }

    handlePointerDown(e) {
      this.miniMapEle.onpointermove = this.handlePointerMove.bind(this);
      this.miniMapEle.style.cursor = 'grabbing';
      this.miniMapEle.setPointerCapture(e.pointerId);
    }

    handlePointerMove(e) {
      if (e.buttons !== 1) {
        this.miniMapEle.onpointermove = null;
        this.miniMapEle.releasePointerCapture(e.pointerId);
        return;
      }
      this.navigator.pan(-e.movementX / this.viewScale, -e.movementY / this.viewScale);
      this.layout();
    }

    handlePointerUp(e) {
      this.miniMapEle.onpointermove = null;
      this.miniMapEle.releasePointerCapture(e.pointerId);
      this.miniMapEle.style.cursor = 'grab';
    }

    layout() {
      const viewportBounds = this.navigator.getViewportBounds();
      const canvasActualBounds = this.navigator.getCanvasActualBounds();
      const canvasScale = this.navigator.getCanvasScale();
      const globalBounds = {
        left: Math.min(viewportBounds.left, canvasActualBounds.left * canvasScale),
        top: Math.min(viewportBounds.top, canvasActualBounds.top * canvasScale),
        right: Math.max(viewportBounds.left + viewportBounds.width, (canvasActualBounds.left + canvasActualBounds.width) * canvasScale),
        bottom: Math.max(viewportBounds.top + viewportBounds.height, (canvasActualBounds.top + canvasActualBounds.height) * canvasScale),
      };
      globalBounds.width = globalBounds.right - globalBounds.left;
      globalBounds.height = globalBounds.bottom - globalBounds.top;
      const miniMapBounds = {
        left: 4,
        top: 4,
        width: this.miniMapEle.offsetWidth - 8,
        height: this.miniMapEle.offsetHeight - 8,
      };
      const viewBounds = {};
      if (miniMapBounds.width / miniMapBounds.height > globalBounds.width / globalBounds.height) {
        viewBounds.height = miniMapBounds.height;
        viewBounds.width = viewBounds.height * (globalBounds.width / globalBounds.height);
        viewBounds.left = miniMapBounds.left + (miniMapBounds.width - viewBounds.width) / 2;
        viewBounds.top = miniMapBounds.top;
      } else {
        viewBounds.width = miniMapBounds.width;
        viewBounds.height = viewBounds.width / (globalBounds.width / globalBounds.height);
        viewBounds.left = miniMapBounds.left;
        viewBounds.top = miniMapBounds.top + (miniMapBounds.height - viewBounds.height) / 2;
      }
      this.viewScale = viewBounds.width / globalBounds.width;
      this.miniMapViewportEle.style.left = `${viewBounds.left}px`;
      this.miniMapViewportEle.style.top = `${viewBounds.top}px`;
      this.miniMapViewportEle.style.width = `${viewportBounds.width}px`;
      this.miniMapViewportEle.style.height = `${viewportBounds.height}px`;
      this.miniMapViewportEle.style.transform = `scale(${this.viewScale}) translate(${-globalBounds.left}px, ${-globalBounds.top}px)`;
      this.miniMapCanvasEle.style.transform = this.canvasEle.style.transform;
    }

    getNodesBoundsString() {
      if (!this.lastGetNodesBoundsStringTime || Date.now() - this.lastGetNodesBoundsStringTime > 200) {
        this.cacheNodesBoundsString = '';
        const elements = this.navigator.jsPlumbInstance.getManagedElements();
        for (const key in elements) {
          const ele = elements[key].el;
          const left = parseInt(ele.offsetLeft);
          const top = parseInt(ele.offsetTop);
          const width = parseInt(ele.offsetWidth);
          const height = parseInt(ele.offsetHeight);
          this.cacheNodesBoundsString += `${left},${top},${width},${height},`;
        }
        this.lastGetNodesBoundsStringTime = Date.now();
      }
      return this.cacheNodesBoundsString;
    }

    createMiniMapViewportEle() {
      const ele = document.createElement('div');
      ele.className = 'minimap-viewport';
      ele.style.position = 'absolute';
      ele.style.transformOrigin = 'left top';
      ele.style.backgroundColor = 'white';
      return ele;
    }

    createMiniMapCanvasEle() {
      const ele = document.createElement('div');
      ele.className = 'minimap-canvas';
      ele.style.position = 'absolute';
      ele.style.transformOrigin = 'left top';
      return ele;
    }

    createNodeOutlineEle(bounds) {
      const ele = document.createElement('div');
      ele.className = 'minimap-node-outline';
      ele.style.position = 'absolute';
      ele.style.left = `${bounds.left}px`;
      ele.style.top = `${bounds.top}px`;
      ele.style.width = `${bounds.width}px`;
      ele.style.height = `${bounds.height}px`;
      ele.style.backgroundColor = '#00000050';
      return ele;
    }

    drawCanvasOutline() {
      this.miniMapCanvasEle.innerHTML = '';
      const fragment = document.createDocumentFragment();
      const elements = this.navigator.jsPlumbInstance.getManagedElements();
      for (const key in elements) {
        const ele = elements[key].el;
        const bounds = { left: ele.offsetLeft, top: ele.offsetTop, width: ele.offsetWidth, height: ele.offsetHeight };
        fragment.appendChild(this.createNodeOutlineEle(bounds));
      }
      this.miniMapCanvasEle.appendChild(fragment);
    }

    refresh(force) {
      if (this.miniMapEle.style.display !== 'none') {
        let redraw = false;
        let relayout = false;
        const nodesBoundsString = this.getNodesBoundsString();
        if (nodesBoundsString !== this.nodesBoundsString) {
          this.nodesBoundsString = nodesBoundsString;
          redraw = true;
          relayout = true;
        }
        if (this.canvasEle.style.transform !== this.canvasEleTransform) {
          this.canvasEleTransform = this.canvasEle.style.transform;
          relayout = true;
        }
        if (relayout || force) {
          if (redraw) {
            this.drawCanvasOutline();
          }
          this.layout();
        }
        if (!this.isDisposed) {
          this.animationFrameHandle = window.requestAnimationFrame(() => this.refresh());
        }
      }
    }

    dispose() {
      window.cancelAnimationFrame(this.animationFrameHandle);
      this.miniMapEle.onpointerdown = null;
      this.miniMapEle.onpointermove = null;
      this.miniMapEle.onpointerup = null;
      this.miniMapEle.removeEventListener('mousewheel', this.handleMiddleMouseZoom);
      this.isDisposed = true;
    }
  }

  class Toolbar {
    zoomInSvg = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#666"><path d="M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z" p-id="8525"></path><path d="M921 867L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z" p-id="8526"></path></svg>`;
    zoomOutSvg = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#666"><path d="M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z" p-id="8665"></path><path d="M921 867L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z" p-id="8666"></path></svg>`;
    zoomTo100Svg = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#666"><path d="M316 672h60c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8zM512 622c22.1 0 40-17.9 40-39 0-23.1-17.9-41-40-41s-40 17.9-40 41c0 21.1 17.9 39 40 39zM512 482c22.1 0 40-17.9 40-39 0-23.1-17.9-41-40-41s-40 17.9-40 41c0 21.1 17.9 39 40 39z" p-id="8805"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H184V184h656v656z" p-id="8806"></path><path d="M648 672h60c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8z" p-id="8807"></path></svg>`;
    bestFitSvg = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#666"><path d="M326 664H104c-8.8 0-16 7.2-16 16v48c0 8.8 7.2 16 16 16h174v176c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V696c0-17.7-14.3-32-32-32zM342 88h-48c-8.8 0-16 7.2-16 16v176H104c-8.8 0-16 7.2-16 16v48c0 8.8 7.2 16 16 16h222c17.7 0 32-14.3 32-32V104c0-8.8-7.2-16-16-16zM920 664H698c-17.7 0-32 14.3-32 32v224c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V744h174c8.8 0 16-7.2 16-16v-48c0-8.8-7.2-16-16-16zM920 280H746V104c0-8.8-7.2-16-16-16h-48c-8.8 0-16 7.2-16 16v224c0 17.7 14.3 32 32 32h222c8.8 0 16-7.2 16-16v-48c0-8.8-7.2-16-16-16z" p-id="9363"></path></svg>`;
    fitToViewportSvg = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#666"><path d="M342 88H120c-17.7 0-32 14.3-32 32v224c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V168h174c8.8 0 16-7.2 16-16v-48c0-8.8-7.2-16-16-16zM920 664h-48c-8.8 0-16 7.2-16 16v176H682c-8.8 0-16 7.2-16 16v48c0 8.8 7.2 16 16 16h222c17.7 0 32-14.3 32-32V680c0-8.8-7.2-16-16-16zM342 856H168V680c0-8.8-7.2-16-16-16h-48c-8.8 0-16 7.2-16 16v224c0 17.7 14.3 32 32 32h222c8.8 0 16-7.2 16-16v-48c0-8.8-7.2-16-16-16zM904 88H682c-8.8 0-16 7.2-16 16v48c0 8.8 7.2 16 16 16h174v176c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V120c0-17.7-14.3-32-32-32z" p-id="9224"></path></svg>`;

    constructor(navigator, toolbarEle) {
      this.navigator = navigator;
      this.toolbarEle = toolbarEle;
      this.toolbarEle.appendChild(this.createTool('放大', this.zoomInSvg, this.navigator.zoomIn.bind(this.navigator)));
      this.toolbarEle.appendChild(this.createTool('缩小', this.zoomOutSvg, this.navigator.zoomOut.bind(this.navigator)));
      this.toolbarEle.appendChild(this.createTool('100%', this.zoomTo100Svg, this.navigator.zoomTo100.bind(this.navigator)));
      this.toolbarEle.appendChild(this.createTool('最佳适应', this.bestFitSvg, this.navigator.bestFit.bind(this.navigator)));
      this.toolbarEle.appendChild(this.createTool('适应画布', this.fitToViewportSvg, this.navigator.fitToViewport.bind(this.navigator), true));
    }

    createTool(title, image, click, last) {
      const button = document.createElement('button');
      button.className = 'tool';
      button.title = title;
      button.innerHTML = image;
      button.onclick = click;
      button.style.width = '16px';
      button.style.height = '16px';
      button.style.padding = '5px';
      button.style.boxSizing = 'content-box';
      button.style.display = 'flex';
      button.style.alignItems = 'center';
      button.style.justifyContent = 'center';
      button.style.border = 'none';
      if (!last) {
        button.style.borderBottom = '1px solid #eee';
      }
      button.style.backgroundColor = 'white';
      button.style.cursor = 'pointer';
      button.style.userSelect = 'none';
      button.onmouseover = () => {
        button.style.backgroundColor = '#f0f0f0';
      };
      button.onmouseout = () => {
        button.style.backgroundColor = 'white';
      };
      return button;
    }
  }

  window.createJsPlumbNavigator = (jsPlumbInstance, options) => {
    const defaultOptions = {
      miniMapWidth: 200,
      miniMapHeight: 150,
      miniMapPosition: 'bottom-right',
      toolbarPosition: 'bottom-left',
      disableMiniMap: false,
      disableToolbar: false,
    };
    const navigator = new Navigator(jsPlumbInstance, { ...defaultOptions, ...options });
    return {
      getZoom: navigator.getCanvasScale.bind(navigator),
      zoomTo: navigator.zoomTo.bind(navigator),
      zoomIn: navigator.zoomIn.bind(navigator),
      zoomOut: navigator.zoomOut.bind(navigator),
      zoomTo100: navigator.zoomTo100.bind(navigator),
      bestFit: navigator.bestFit.bind(navigator),
      fitToViewport: navigator.fitToViewport.bind(navigator),
      getMiniMapVisible: navigator.getMiniMapVisible.bind(navigator),
      showMiniMap: navigator.showMiniMap.bind(navigator),
      hideMiniMap: navigator.hideMiniMap.bind(navigator),
      getToolbarVisible: navigator.getToolbarVisible.bind(navigator),
      showToolbar: navigator.showToolbar.bind(navigator),
      hideToolbar: navigator.hideToolbar.bind(navigator),
      dispose: navigator.dispose.bind(navigator),
    };
  };
})();
